package seGobangClient.gaming;

import javax.vecmath.Point2i;
import seGobangClient.GlobalController;
import seGobangClient.ICommand;
import seGobangClient.IMessageBox;

/**
 *
 * @author plus
 */
public class GamingCommandsFactory {
    class CommandAddBlackChess implements ICommand{
        private IGamingScene Receiver;

        public CommandAddBlackChess(IGamingScene Receiver) {
            this.Receiver = Receiver;
        }
        
        public Object execute(Object Param) {
            Receiver.setChess((Point2i)Param, (byte)-1);
            return null;
        }

        public Object undo() {
            throw new UnsupportedOperationException("Not supported yet.");
        }
        
    }
    
    class CommandAddWhiteChess implements ICommand{
        private IGamingScene Receiver;

        public CommandAddWhiteChess(IGamingScene Receiver) {
            this.Receiver = Receiver;
        }
        
        public Object execute(Object Param) {
            Receiver.setChess((Point2i)Param, (byte)1);
            return null;
        }

        public Object undo() {
            throw new UnsupportedOperationException("Not supported yet.");
        }
        
    }
    
    class CommandAIFx implements ICommand{
        private IGamingScene Receiver;

        public CommandAIFx(IGamingScene Receiver) {
            this.Receiver = Receiver;
        }
        
        public Object execute(Object Param) {
            Receiver.AIFx((Point2i)Param, IGamingScene.AIFx_PUT);
            return new Object();
        }

        public Object undo() {
            throw new UnsupportedOperationException("Not supported yet.");
        }
    }
    
    class CommandAIFxWin implements ICommand{
        private IGamingScene Receiver;

        public CommandAIFxWin(IGamingScene Receiver) {
            this.Receiver = Receiver;
        }
        
        public Object execute(Object Param) {
            Receiver.AIFx((Point2i)Param, IGamingScene.AIFx_WIN);
            return new Object();
        }

        public Object undo() {
            throw new UnsupportedOperationException("Not supported yet.");
        }
    }
    
     class CommandRemoveChess implements ICommand{
        private IGamingScene Receiver;

        public CommandRemoveChess(IGamingScene Receiver) {
            this.Receiver = Receiver;
        }
        
        public Object execute(Object Param) {
            Receiver.setChess((Point2i)Param, (byte)0);
            return null;
        }

        public Object undo() {
            throw new UnsupportedOperationException("Not supported yet.");
        }
    }
     
     class CommandUpdatePlayerInfo implements ICommand{
        private IGamingScene Receiver;
        private IPlayer player1,player2;

        public CommandUpdatePlayerInfo(IGamingScene Receiver,IPlayer player1, IPlayer player2) {
            this.Receiver = Receiver;
            this.player1=player1;
            this.player2=player2;
        }
        
        public Object execute(Object Param) {
            Receiver.updatePlayerInfo(player1, player2);
            return new Object();
        }

        public Object undo() {
            throw new UnsupportedOperationException("Not supported yet.");
        }
    }
     
    class CommandMarkCurrentPlayer implements ICommand{
        private IGamingScene Receiver;

        public CommandMarkCurrentPlayer(IGamingScene Receiver) {
            this.Receiver = Receiver;
        }
        
        public Object execute(Object Param) {
            Receiver.setCurrentPlayer(((IPlayer)Param).getChessFlag());
            return new Object();
        }

        public Object undo() {
            throw new UnsupportedOperationException("Not supported yet.");
        }
    }
          
     class CommandEnableLocalInput implements ICommand{
        private IGamingScene Receiver;

        public CommandEnableLocalInput(IGamingScene Receiver) {
            this.Receiver = Receiver;
        }
        
        public Object execute(Object Param) {
            Receiver.setChessBoardPickable(true);
            return null;
        }

        public Object undo() {
            throw new UnsupportedOperationException("Not supported yet.");
        }
    }
     
     class CommandDisableLocalInput implements ICommand{
        private IGamingScene Receiver;

        public CommandDisableLocalInput(IGamingScene Receiver) {
            this.Receiver = Receiver;
        }
        
        public Object execute(Object Param) {
            Receiver.setChessBoardPickable(false);
            return null;
        }

        public Object undo() {
            throw new UnsupportedOperationException("Not supported yet.");
        }
    }
     
     class CommandBlackChessPut implements ICommand{
        private ChessBoard Receiver;
        private GamingController Controller;

        public CommandBlackChessPut(ChessBoard Receiver,GamingController Controller) {
            this.Receiver = Receiver;
            this.Controller=Controller;
        }
        
        public Object execute(Object Param) {
            if(1==Receiver.putChess((Point2i) Param, (byte)-1)){                //未发生游戏中止才能交换玩家
                Controller.currentPlayer.turnOver(false);
                swapPlayers();
                Controller.currentPlayer.turnToMe();
            }
            return null;
        }

        public Object undo() {
            throw new UnsupportedOperationException("Not supported yet.");
        }
        
        private void swapPlayers(){
            IPlayer tempPlayer;
            tempPlayer=Controller.waitingPlayer;
            Controller.waitingPlayer=Controller.currentPlayer;
            Controller.currentPlayer=tempPlayer;
        }
    }     
     
     class CommandWhiteChessPut implements ICommand{
        private ChessBoard Receiver;
        private GamingController Controller;

        public CommandWhiteChessPut(ChessBoard Receiver,GamingController Controller) {
            this.Receiver = Receiver;
            this.Controller=Controller;
        }
        
        public Object execute(Object Param) {
            if(1==Receiver.putChess((Point2i) Param, (byte)1)){                //未发生游戏中止才能交换玩家
                Controller.currentPlayer.turnOver(false);
                swapPlayers();
                Controller.currentPlayer.turnToMe();
            }
           
            return null;
        }

        public Object undo() {
            throw new UnsupportedOperationException("Not supported yet.");
        }
        
        private void swapPlayers(){
            IPlayer tempPlayer;
            tempPlayer=Controller.waitingPlayer;
            Controller.waitingPlayer=Controller.currentPlayer;
            Controller.currentPlayer=tempPlayer;
        }
    }
     
      class CommandRaiseRegret implements ICommand{
        private ChessBoard Receiver;
        private GamingController Controller;

        public CommandRaiseRegret(ChessBoard Receiver,GamingController Controller) {
            this.Receiver = Receiver;
            this.Controller=Controller;
        }
        
        public Object execute(Object Param) {
            int res=Receiver.regret((Byte)Param);
            switch(res){
                case 0:{
                    ((IMessageBox)Controller.Scene).showMessageBox(
                            IMessageBox.TYPE_INFO, "无法悔棋", "您一步子都没走，无法悔棋！", null);
                    break;
                }
                case 1:{
                    Controller.waitingPlayer.turnOver(true);
                    Controller.currentPlayer.turnOver(false);
                    swapPlayers();
                    Controller.currentPlayer.turnToMe();
                    break;
                }
                case 2:{
                    Controller.currentPlayer.turnOver(true);
                    Controller.waitingPlayer.turnOver(true);
                    Controller.currentPlayer.turnToMe();
                    break;
                }
            }
            return res;
        }

        public Object undo() {
            throw new UnsupportedOperationException("Not supported yet.");
        }
        
        private void swapPlayers(){
            IPlayer tempPlayer;
            tempPlayer=Controller.waitingPlayer;
            Controller.waitingPlayer=Controller.currentPlayer;
            Controller.currentPlayer=tempPlayer;
        }
    }
      
    class CommandRaiseSurrender implements ICommand{       
        private GamingController Controller;

        public CommandRaiseSurrender(GamingController Controller) {
            this.Controller=Controller;
        }
        public Object execute(Object Param) {
            IPlayer Raiser=null;
            if (Param!=null) Raiser=(IPlayer)Param;
            if (Raiser instanceof LocalPlayer || Raiser instanceof AIPlayer){
                if (Raiser.equals(Controller.currentPlayer)){
                    Controller.currentPlayer.gameResult(IPlayer.RESULT_SURRENDERED);
                    Controller.waitingPlayer.gameResult(IPlayer.RESULT_OPP_SURRENDERED);
                }else{
                    Controller.currentPlayer.gameResult(IPlayer.RESULT_OPP_SURRENDERED);
                    Controller.waitingPlayer.gameResult(IPlayer.RESULT_SURRENDERED);
                }
                ((IMessageBox) Controller.Scene).showMessageBox(
                        IMessageBox.TYPE_QUESTION, "游戏结束",
                        "<html>"+Raiser.getPlayerName()+"投降了!<br>再来一盘吗？</html>",
                        "EndGame");
            }else if (Raiser instanceof OnlineLocalPlayer){
                    Controller.currentPlayer.gameResult(IPlayer.RESULT_SURRENDERED);
                    Controller.waitingPlayer.gameResult(IPlayer.RESULT_OPP_SURRENDERED);
                    ((IMessageBox) Controller.Scene).showMessageBox(
                        IMessageBox.TYPE_INFO, "败北",
                        "<html>你投降了!<br>请再接再厉！</html>",
                        "ReturnHall");
            }else{
                Controller.currentPlayer.gameResult(IPlayer.RESULT_OPP_SURRENDERED);
                Controller.waitingPlayer.gameResult(IPlayer.RESULT_SURRENDERED);
                ((IMessageBox) Controller.Scene).showMessageBox(
                        IMessageBox.TYPE_INFO, "胜出",
                        "<html>你的对手投降了!<br>恭喜你取得胜利！</html>",
                        "ReturnHall");
            }
            return null;
        }

        public Object undo() {
            throw new UnsupportedOperationException("Not supported yet.");
        }
    }
    
    class CommandSomeoneTimeout implements ICommand{    
        private GamingController Controller;

        public CommandSomeoneTimeout(GamingController Controller) {
            this.Controller=Controller;
        }
        public Object execute(Object Param) {
            IPlayer Raiser=Controller.currentPlayer;
            
            if (Raiser instanceof LocalPlayer || Raiser instanceof AIPlayer){
                Controller.currentPlayer.gameResult(IPlayer.RESULT_TIMEOUT);
                Controller.waitingPlayer.gameResult(IPlayer.RESULT_OPP_TIMEOUT);
                ((IMessageBox) Controller.Scene).showMessageBox(
                    IMessageBox.TYPE_QUESTION, "游戏结束",
                    "<html>"+Controller.currentPlayer.getPlayerName()+"没时间了!<br>再来一盘吗？</html>",
                    "EndGame");
                
            }else if (Raiser instanceof OnlineLocalPlayer){
                    Controller.currentPlayer.gameResult(IPlayer.RESULT_TIMEOUT);
                    Controller.waitingPlayer.gameResult(IPlayer.RESULT_OPP_TIMEOUT);
                    ((IMessageBox) Controller.Scene).showMessageBox(
                        IMessageBox.TYPE_INFO, "败北",
                        "<html>你没有时间了!<br>请再接再厉！</html>",
                        "ReturnHall");
            }else{
                Controller.currentPlayer.gameResult(IPlayer.RESULT_OPP_TIMEOUT);
                Controller.waitingPlayer.gameResult(IPlayer.RESULT_TIMEOUT);
                ((IMessageBox) Controller.Scene).showMessageBox(
                        IMessageBox.TYPE_INFO, "胜出",
                        "<html>你的对手没时间了!<br>恭喜你取得胜利！</html>",
                        "ReturnHall");
            }
            
            return null;
        }

        public Object undo() {
            throw new UnsupportedOperationException("Not supported yet.");
        }
    }
    
    class CommandWin implements ICommand{    
        private GamingController Controller;

        public CommandWin(GamingController Controller) {
            this.Controller=Controller;
        }
        
        public Object execute(Object Param) {
            IPlayer Raiser=Controller.currentPlayer;
            
            if (Raiser instanceof LocalPlayer || Raiser instanceof AIPlayer){
                Controller.currentPlayer.gameResult(IPlayer.RESULT_WIN);
                Controller.waitingPlayer.gameResult(IPlayer.RESULT_LOST);

                ((IMessageBox) Controller.Scene).showMessageBox(
                    IMessageBox.TYPE_QUESTION, "游戏结束",
                    "<html>"+Controller.currentPlayer.getPlayerName()+"获胜了!<br>再来一盘吗？</html>",
                    "EndGame");
                
            }else if (Raiser instanceof OnlineLocalPlayer){
                    Controller.currentPlayer.gameResult(IPlayer.RESULT_WIN);
                    Controller.waitingPlayer.gameResult(IPlayer.RESULT_LOST);
                    ((IMessageBox) Controller.Scene).showMessageBox(
                        IMessageBox.TYPE_INFO, "胜出",
                        "<html>你获得了胜利!<br>恭喜！</html>",
                        "ReturnHall");
            }else{
                Controller.currentPlayer.gameResult(IPlayer.RESULT_OPP_TIMEOUT);
                Controller.waitingPlayer.gameResult(IPlayer.RESULT_TIMEOUT);
                ((IMessageBox) Controller.Scene).showMessageBox(
                        IMessageBox.TYPE_INFO, "败北",
                        "<html>你输掉了这个棋局!<br>请再接再厉！</html>",
                        "ReturnHall");
            }
            
            
            return null;
        }

        public Object undo() {
            throw new UnsupportedOperationException("Not supported yet.");
        }
    }
    
    class CommandForbidden implements ICommand{    
        private GamingController Controller;

        public CommandForbidden(GamingController Controller) {
            this.Controller=Controller;
        }
        
        public Object execute(Object Param) {
            IPlayer Raiser=Controller.currentPlayer;
            
            if (Raiser instanceof LocalPlayer || Raiser instanceof AIPlayer){
                Controller.currentPlayer.gameResult(IPlayer.RESULT_FORBIDDEN);
                Controller.waitingPlayer.gameResult(IPlayer.RESULT_OPP_FORBIDDEN);
                ((IMessageBox) Controller.Scene).showMessageBox(
                        IMessageBox.TYPE_QUESTION, "游戏结束",
                        "<html>"+Controller.currentPlayer.getPlayerName()+"由于禁手而败北了!<br>再来一盘吗？</html>",
                        "EndGame");
                
            }else if (Raiser instanceof OnlineLocalPlayer){
                    Controller.currentPlayer.gameResult(IPlayer.RESULT_FORBIDDEN);
                    Controller.waitingPlayer.gameResult(IPlayer.RESULT_OPP_FORBIDDEN);
                    ((IMessageBox) Controller.Scene).showMessageBox(
                        IMessageBox.TYPE_INFO, "败北",
                        "<html>由于禁手,你输掉了这个棋局!<br>请再接再厉！</html>",
                        "ReturnHall");
            }else{
                Controller.currentPlayer.gameResult(IPlayer.RESULT_OPP_FORBIDDEN);
                Controller.waitingPlayer.gameResult(IPlayer.RESULT_FORBIDDEN);
                ((IMessageBox) Controller.Scene).showMessageBox(
                        IMessageBox.TYPE_INFO, "胜出",
                        "<html>由于黑方禁手,你获得了胜利!<br>恭喜！</html>",
                        "ReturnHall");
            }
            return null;
        }

        public Object undo() {
            throw new UnsupportedOperationException("Not supported yet.");
        }
    }
    
    class CommandDraw implements ICommand{    
        private GamingController Controller;

        public CommandDraw(GamingController Controller) {
            this.Controller=Controller;
        }
        
        public Object execute(Object Param) {
            Controller.currentPlayer.gameResult(IPlayer.RESULT_DRAW);
            Controller.waitingPlayer.gameResult(IPlayer.RESULT_DRAW);
            ((IMessageBox) Controller.Scene).showMessageBox(
                    IMessageBox.TYPE_QUESTION, "游戏结束",
                    "<html>"+Controller.currentPlayer.getPlayerName()+"双方战平!<br>再来一盘吗？</html>",
                    "EndGame");
            
            return null;
        }

        public Object undo() {
            throw new UnsupportedOperationException("Not supported yet.");
        }
    }

   
    class CommandHaltGame implements ICommand{    
        private GamingController Controller;

        public CommandHaltGame(GamingController Controller) {
            this.Controller=Controller;
        }
        
        public Object execute(Object Param) {
            Controller.currentPlayer.gameResult(0); //NO Result
            Controller.waitingPlayer.gameResult(0);

            ((IMessageBox) Controller.Scene).showMessageBox(
                    IMessageBox.TYPE_QUESTION, "结束棋局",
                    "<html>结束当前棋局!<br>再来一盘吗？</html>",
                    "EndGame");
            return null;
        }

        public Object undo() {
            throw new UnsupportedOperationException("Not supported yet.");
        }
    }
        
    class CommandChooseChessBoard implements ICommand{    
        private GamingController Controller;

        public CommandChooseChessBoard(GamingController Controller) {
            this.Controller=Controller;
        }
        
        public Object execute(Object Param) {
            Controller.currentPlayer.putChess((Point2i)Param);
            return null;
        }

        public Object undo() {
            throw new UnsupportedOperationException("Not supported yet.");
        }
    }
    
    class CommandTestPosition implements ICommand{    
        private GamingController Controller;

        public CommandTestPosition(GamingController Controller) {
            this.Controller=Controller;
        }
        
        public Object execute(Object Param) {
            return Controller.currentChessBoard.testPosition((Point2i)Param);
        }

        public Object undo() {
            throw new UnsupportedOperationException("Not supported yet.");
        }
    }

    class CommandChooseRegret implements ICommand{    
        private GamingController Controller;

        public CommandChooseRegret(GamingController Controller) {
            this.Controller=Controller;
        }
        
        public Object execute(Object Param) {
            byte chessflag=(Byte) Param;
            if (Controller.currentPlayer.getChessFlag()==chessflag)
                Controller.currentPlayer.regret();
            else
                Controller.waitingPlayer.regret();
            return null;
        }

        public Object undo() {
            throw new UnsupportedOperationException("Not supported yet.");
        }
    }
    
    class CommandChooseSurrender implements ICommand{    
        private GamingController Controller;

        public CommandChooseSurrender(GamingController Controller) {
            this.Controller=Controller;
        }
        
        public Object execute(Object Param) {
            byte chessflag=(Byte) Param;
            if (Controller.currentPlayer.getChessFlag()==chessflag)
                Controller.currentPlayer.surrender();
            else
                Controller.waitingPlayer.surrender();
            return null;
        }

        public Object undo() {
            throw new UnsupportedOperationException("Not supported yet.");
        }
    }
    
    class CommandEndGame implements ICommand{    
        private GamingController Controller;

        public CommandEndGame(GamingController Controller) {
            this.Controller=Controller;
        }
        
        public Object execute(Object Param) {
            int res = (Integer) Param;
            if (res == 1) {     //ReGame
                //Controller.doEvent("DisableLocalInput", null);
                Controller.waitingPlayer.turnOver(false);
                Controller.currentPlayer.turnOver(false);
                
                Controller.currentPlayer.resetPlayer();
                Controller.waitingPlayer.resetPlayer();
                Controller.currentChessBoard.clearChessBoard();
                if (Controller.currentPlayer.getChessFlag() != -1) {
                    IPlayer tempPlayer;
                    tempPlayer = Controller.waitingPlayer;
                    Controller.waitingPlayer = Controller.currentPlayer;
                    Controller.currentPlayer = tempPlayer;
                }
                Controller.currentPlayer.turnToMe();
            }else{              //ChangeToMainMenu
               // Controller.doEvent("DisableLocalInput", null);
                Controller.waitingPlayer.turnOver(false);
                Controller.currentPlayer.turnOver(false);
                GlobalController.setCurrentSceneController(
                        new seGobangClient.mainMenu.MainMenuController(GlobalController.getCurrentUISystem()));
            }
            return null;
        }

        public Object undo() {
            throw new UnsupportedOperationException("Not supported yet.");
        }
    }
    
    
    class CommandReturnHall implements ICommand{    
        private GamingController Controller;

        public CommandReturnHall(GamingController Controller) {
            this.Controller=Controller;
        }
        
        public Object execute(Object Param) {
                Controller.waitingPlayer.turnOver(false);
                Controller.currentPlayer.turnOver(false);
                GlobalController.setCurrentSceneController(
                        Controller.OnlineHall);
                Controller.OnlineHall.returnToDesk();
            return null;
        }

        public Object undo() {
            throw new UnsupportedOperationException("Not supported yet.");
        }
    }
    
    /*由UI发起的命令*/
    ICommand createChooseChessBoardCommand(GamingController controller){
        return new CommandChooseChessBoard(controller);
    }
    
    ICommand createChooseRegretCommand(GamingController controller){
        return new CommandChooseRegret(controller);
    }
    
    ICommand createChooseSurrenderCommand(GamingController controller){
        return new CommandChooseSurrender(controller);
    }
    
    ICommand createEndGameCommand(GamingController controller){
        return new CommandEndGame(controller);
    }
    
    ICommand createTestPosition(GamingController controller){
        return new CommandTestPosition(controller);
    }
    
    /*由棋盘发起的命令*/
    ICommand createAddBlackChessCommand(IGamingScene scene){
        return new CommandAddBlackChess(scene);
    }
    
    ICommand createAddWhiteChessCommand(IGamingScene scene){
        return new CommandAddWhiteChess(scene);
    }
    
    ICommand createRemoveChessCommand(IGamingScene scene){
        return new CommandRemoveChess(scene);
    }
    
    ICommand createWinCommand(GamingController controller){
        return new CommandWin(controller);
    }
    
    ICommand createDrawCommand(GamingController controller){
        return new CommandWin(controller);
    }
    
    ICommand createForbiddenCommand(GamingController controller){
        return new CommandForbidden(controller);
    }
    
    
    /*由玩家发起的命令*/
    ICommand createDisableLocalInputCommand(IGamingScene scene){
        return new CommandDisableLocalInput(scene);
    }
    
    ICommand createEnableLocalInputCommand(IGamingScene scene){
        return new CommandEnableLocalInput(scene);
    }
    
    ICommand createUpdatePlayerInfoCommand(IGamingScene scene,IPlayer p1, IPlayer p2){
        return new CommandUpdatePlayerInfo(scene,p1,p2);
    }
    
    ICommand createAIFx(IGamingScene scene){
        return new CommandAIFx(scene);
    }
    
    ICommand createAIFxWin(IGamingScene scene){
        return new CommandAIFxWin(scene);
    }
    
    ICommand createMarkCurrentPlayerCommand(IGamingScene scene){
        return new CommandMarkCurrentPlayer(scene);
    }
        
    ICommand createBlackChessPutCommand(ChessBoard board,GamingController controller){
        return new CommandBlackChessPut(board,controller);
    }
    
    ICommand createWhiteChessPutCommand(ChessBoard board,GamingController controller){
        return new CommandWhiteChessPut(board,controller);
    }
    
    ICommand createRaiseRegretCommand(ChessBoard board,GamingController controller){
        return new CommandRaiseRegret(board,controller);
    }
    
    ICommand createRaiseSurrenderCommand(GamingController controller){
        return new CommandRaiseSurrender(controller);
    }
    
    ICommand createSomeoneTimeoutCommand(GamingController controller){
        return new CommandSomeoneTimeout(controller);
    }
    
    ICommand createHaltGameCommand(GamingController controller){
        return new CommandHaltGame(controller);
    }
    
    ICommand createReturnHallCommand(GamingController controller){
        return new CommandReturnHall(controller);
    }
}
